/**
 * 
 */
package any.gwt.client.ui;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.ClickListenerCollection;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasWordWrap;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.MouseListenerCollection;
import com.google.gwt.user.client.ui.MouseWheelListener;
import com.google.gwt.user.client.ui.MouseWheelListenerCollection;
import com.google.gwt.user.client.ui.SourcesClickEvents;
import com.google.gwt.user.client.ui.SourcesMouseEvents;
import com.google.gwt.user.client.ui.SourcesMouseWheelEvents;
import com.google.gwt.user.client.ui.Widget;

/**
 * TODO: Doc me
 * 
 * @author keke <keke@codehaus.org>
 * @version
 * @revision $Revision:$
 */
public class Span extends Widget implements SourcesClickEvents,
        SourcesMouseEvents, SourcesMouseWheelEvents, HasHorizontalAlignment,
        HasText, HasWordWrap {

    private ClickListenerCollection      clickListeners;
    private HorizontalAlignmentConstant  horzAlign;
    private MouseListenerCollection      mouseListeners;
    private MouseWheelListenerCollection mouseWheelListeners;

    /**
     * Creates an empty label.
     */
    public Span() {
        setElement(DOM.createSpan());
        sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS | Event.ONMOUSEWHEEL);
        setStyleName("span");
    }

    /**
     * Creates a label with the specified text.
     * 
     * @param text
     *            the new label's text
     */
    public Span(final String text) {
        this();
        setText(text);
    }

    /**
     * Creates a label with the specified text.
     * 
     * @param text
     *            the new label's text
     * @param wordWrap
     *            <code>false</code> to disable word wrapping
     */
    public Span(final String text, final boolean wordWrap) {
        this(text);
        setWordWrap(wordWrap);
    }

    public void addClickListener(final ClickListener listener) {
        if (clickListeners == null) {
            clickListeners = new ClickListenerCollection();
        }
        clickListeners.add(listener);
    }

    public void addMouseListener(final MouseListener listener) {
        if (mouseListeners == null) {
            mouseListeners = new MouseListenerCollection();
        }
        mouseListeners.add(listener);
    }

    public void addMouseWheelListener(final MouseWheelListener listener) {
        if (mouseWheelListeners == null) {
            mouseWheelListeners = new MouseWheelListenerCollection();
        }
        mouseWheelListeners.add(listener);
    }

    public HorizontalAlignmentConstant getHorizontalAlignment() {
        return horzAlign;
    }

    public String getText() {
        return DOM.getInnerText(getElement());
    }

    public boolean getWordWrap() {
        return !DOM.getStyleAttribute(getElement(), "whiteSpace").equals(
                "nowrap");
    }

    public void onBrowserEvent(final Event event) {
        switch (DOM.eventGetType(event)) {
        case Event.ONCLICK:
            if (clickListeners != null) {
                clickListeners.fireClick(this);
            }
            break;

        case Event.ONMOUSEDOWN:
        case Event.ONMOUSEUP:
        case Event.ONMOUSEMOVE:
        case Event.ONMOUSEOVER:
        case Event.ONMOUSEOUT:
            if (mouseListeners != null) {
                mouseListeners.fireMouseEvent(this, event);
            }
            break;

        case Event.ONMOUSEWHEEL:
            if (mouseWheelListeners != null) {
                mouseWheelListeners.fireMouseWheelEvent(this, event);
            }
            break;
        }
    }

    public void removeClickListener(final ClickListener listener) {
        if (clickListeners != null) {
            clickListeners.remove(listener);
        }
    }

    public void removeMouseListener(final MouseListener listener) {
        if (mouseListeners != null) {
            mouseListeners.remove(listener);
        }
    }

    public void removeMouseWheelListener(final MouseWheelListener listener) {
        if (mouseWheelListeners != null) {
            mouseWheelListeners.remove(listener);
        }
    }

    public void setHorizontalAlignment(final HorizontalAlignmentConstant align) {
        horzAlign = align;
        DOM.setStyleAttribute(getElement(), "textAlign", align
                .getTextAlignString());
    }

    public void setText(final String text) {
        DOM.setInnerText(getElement(), text);
    }

    public void setWordWrap(final boolean wrap) {
        DOM.setStyleAttribute(getElement(), "whiteSpace", wrap ? "normal"
                : "nowrap");
    }
}